/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.digitalization.service.impl;

import cn.hutool.core.lang.Pair;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Triple;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.digitalization.contant.ConstantDigit;
import org.springblade.modules.digitalization.dto.*;
import org.springblade.modules.digitalization.entity.ManageArchivesEntity;
import org.springblade.modules.digitalization.entity.ManageRsdamlEntity;
import org.springblade.modules.digitalization.entity.ManageRsdawjEntity;
import org.springblade.modules.digitalization.excel.ManageRsdamlExcel;
import org.springblade.modules.digitalization.manager.LogManager;
import org.springblade.modules.digitalization.mapper.ManageRsdamlMapper;
import org.springblade.modules.digitalization.mapper.ManageRsdawjMapper;
import org.springblade.modules.digitalization.service.IManageArchivesService;
import org.springblade.modules.digitalization.service.IManageRsdamlService;
import org.springblade.modules.digitalization.service.IManageRsdawjService;
import org.springblade.modules.digitalization.utils.CommonDataListener;
import org.springblade.modules.digitalization.utils.DaUtils;
import org.springblade.modules.digitalization.utils.ExcelExportUtil;
import org.springblade.modules.digitalization.vo.CatalogItem;
import org.springblade.modules.digitalization.vo.ManageRsdamlVO;
import org.springblade.modules.digitalization.vo.ManageRsdawjVO;
import org.springblade.modules.digitalization.wrapper.UserMenuRs;
import org.springblade.modules.system.entity.Dict;
import org.springblade.modules.system.service.IDictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 干部人事档案目录信息表-JAVA 服务实现类
 *
 * @author Rs
 * @since 2023-01-07
 */
@Service
@Slf4j
@Getter
public class ManageRsdamlServiceImpl extends BaseServiceImpl<ManageRsdamlMapper, ManageRsdamlEntity> implements IManageRsdamlService {

	@Autowired
	private IDictService dictService;
	@Autowired
	IManageArchivesService manageArchivesService;
	@Autowired
	private IManageRsdawjService rsdawjService;

	@Resource
	private ManageRsdawjMapper rsdawjMapper;
	@Autowired
	private LogManager logManager;

	public final static String CATALOG_DIR_DICT = "archive_catalog_class";


	public Map<String, List<ManageRsdamlExcel>> mlErrorMaps = Maps.newHashMap();
	@Autowired
	private A01ServiceImpl a01ServiceImpl;

	@Scheduled(cron = "0 0 23 * * ?")
	public void execDeletMapData() {
		mlErrorMaps.clear();
	}

	@Override
	public IPage<ManageRsdamlVO> selectManageRsdamlPage(IPage<ManageRsdamlVO> page, ManageRsdamlVO rsdaml) {
		return page.setRecords(baseMapper.selectManageRsdamlPage(page, rsdaml));
	}

	@Override
	public List<CatalogItem> slectCatalogItem(SelectRsdamlRead selectRsdamlRead) {
		LocalDateTime startTime = LocalDateTime.now();
//		log.info("目录：{}，{}，获取请求时间：{}", selectRsdamlRead.getA0000(), selectRsdamlRead.getSerialNumber(), startTime.format(DateTimeFormatter.ofPattern
//		("yyyy-MM-dd HH:mm:ss:SSS")));
		//获取权限
		List<ManageRsdamlEntity> rsdamlList = this.baseMapper.selectByArchiveId(selectRsdamlRead.getA0000());
		//生成目录
		if (rsdamlList.isEmpty()) {
			return Collections.emptyList();
		}
		List<CatalogItem> catalogItems = createCatalogDirs();
		//关联档案
		for (ManageRsdamlEntity rsdaml : rsdamlList) {
			CatalogItem catalogItem = new CatalogItem(rsdaml);
			CatalogItem parentCatalogItem = getParentCatalogItem(catalogItems, catalogItem);
			if (parentCatalogItem != null) {
				//catalogItem.setClassNo(parentCatalogItem.getChildren().size()+1+"");
				catalogItem.setParentId(parentCatalogItem.getId());
				parentCatalogItem.getChildren().add(catalogItem);
				parentCatalogItem.setA0000(selectRsdamlRead.getA0000());
				updateCatalogCount(parentCatalogItem, rsdaml.getRsdaml005());
			}
		}
		removeEmptyCatalog(catalogItems);
		return catalogItems;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public List<ManageRsdamlExcel> doImport(MultipartFile file, String a0000, Integer status) {
		ManageArchivesEntity one = manageArchivesService.getOne(Wrappers.<ManageArchivesEntity>lambdaQuery().eq(ManageArchivesEntity::getA0000,
			a0000));
		if (Func.isEmpty(one)) {
			throw new ServiceException("请选择人员");
		}
		//读取文件内容
		CommonDataListener<ManageRsdamlExcel> dictListener = new CommonDataListener<ManageRsdamlExcel>();
		try {
			EasyExcel.read(file.getInputStream(), ManageRsdamlExcel.class, dictListener).sheet().headRowNumber(2).doRead();
		} catch (IOException e) {
			e.printStackTrace();
		}
		List<ManageRsdamlExcel> datas = dictListener.getData();
		List<ManageRsdamlExcel> errData = Lists.newArrayList();
		Map<String, Integer> xuhaoMap = Maps.newConcurrentMap();
		List<ManageRsdamlEntity> importDatas = Lists.newArrayList();
		if (Func.isEmpty(datas)) {
			throw new ServiceException("数据为空");
		}

		for (ManageRsdamlExcel data : datas) {
			if (Func.isBlank(data.getRsdaml002()) || Func.isBlank(data.getRsdaml004())) {
				throw new ServiceException("数据内容为空或格式错误");
			}
			ManageRsdamlEntity tmpentity = null;
			if (Func.isBlank(data.getRsdaml002())) {
				break;
			} else {
				tmpentity = new ManageRsdamlEntity();
				BeanUtil.copy(data, tmpentity);
				Integer integer1 = ConstantDigit.sortClassMap.get(data.getRsdaml002());
				if (Func.isNull(integer1)) {
					data.setErrorMsg("类号错误");
					errData.add(data);
					continue;
				} else {
					tmpentity.setClassSort(integer1);
				}
				Integer integer = xuhaoMap.get(data.getRsdaml002());
				if (Func.isNull(integer)) {
					integer = 0;
				}
				integer++;
				xuhaoMap.put(data.getRsdaml002(), integer);
				tmpentity.setRsdaml003(integer);
				if (Func.isNotBlank(data.getFormationTime())) {
					try {
						Triple<String, String, String> date = ExcelExportUtil.getDate(data.getFormationTime());
						tmpentity.setRsdaml006(date.getLeft());
						tmpentity.setRsdaml007(date.getMiddle());
						tmpentity.setRsdaml008(date.getRight());
					} catch (Exception e) {
						data.setErrorMsg(e.getMessage());
						errData.add(data);
						continue;
					}
				}

				if (Func.isBlank(data.getRsdaml004())) {
					data.setErrorMsg("材料名称不可为空");
					errData.add(data);
					continue;
				}
				if (Func.isEmpty(data.getRsdaml005())) {
					data.setErrorMsg("页数不可为空");
					errData.add(data);
					continue;
				}
				tmpentity.setArchiveId(one.getArchiveId());
				tmpentity.setA0000(one.getA0000());

				tmpentity.setRsdaml000(IdUtil.randomUUID());

				if (StringUtils.isEmpty(data.getRemark())) {
					tmpentity.setRsdaml009(data.getErrorMsg());
				} else {
					tmpentity.setRsdaml009(data.getRemark());
				}
				DaUtils.convertChineseRightQuote(tmpentity);

				tmpentity.setStatus(status);
				importDatas.add(tmpentity);
			}
		}
		if (Func.isEmpty(errData)) {
			// 非散材料的情况下清空现有数据
			if (NumberUtil.equals(status, 1)) {
				remove(Wrappers.<ManageRsdamlEntity>lambdaQuery().eq(ManageRsdamlEntity::getA0000, a0000));
			}
			saveBatch(importDatas);
			this.saveSorts(a0000);

			importDatas.parallelStream().forEach(item -> {
				logManager.doImport(a0000, LogManager.TYPE_ML, item);
			});
		} else {
			mlErrorMaps.remove(a0000);
			mlErrorMaps.put(a0000, errData);
		}
		return errData;
	}

	@Override
	public List<ManageRsdamlExcel> getMlErrorMaps(String a0000) {
		return mlErrorMaps.get(a0000);
	}

	@Override
	public Integer getClassMap(String rsdaml002) {
		return ConstantDigit.sortClassMap.get(rsdaml002);
	}

	@Override
	public List<UserMenuRs> getMenusByA0000(String a0000) {
		List<UserMenuRs> result = baseMapper.selectUserMenuByA0000(a0000);
		result.stream().forEach(a -> {
			List<ManageRsdawjVO> wjByMu = rsdawjMapper.getWjByMu(a.getTmpOrg());
			wjByMu.stream().forEach(b -> {
				a.getHdImgs().add(b.getRsdawj003());
				a.getOrgImgs().add(b.getRsdawj004());
			});
		});

		return result;
	}

	@Autowired
	private JdbcTemplate jdbcTemplate;

	@Override
	public List<ManageRsdamlVO> listWithPage(ManageRsdamlEntity rsdaml) {

		List<ManageRsdamlEntity> list = list(Condition.getQueryWrapper(rsdaml).orderByAsc("class_sort").orderByAsc("rsdaml003"));
		List<ManageRsdamlVO> result = Lists.newArrayList();

		List<ManageRsdawjEntity> rsdawjEntitiesAll = rsdawjMapper.selectList(Wrappers.<ManageRsdawjEntity>lambdaQuery()
			.eq(ManageRsdawjEntity::getA0000, rsdaml.getA0000())
			.isNotNull(ManageRsdawjEntity::getRsdawj000)
		);

		Map<String, List<ManageRsdawjEntity>> rsdamawjMap = rsdawjEntitiesAll.stream()
			.collect(Collectors.groupingBy(ManageRsdawjEntity::getRsdawj000));

		list.stream().forEach(a -> {
			ManageRsdamlVO manageRsdamlVO = new ManageRsdamlVO();
			Func.copy(a, manageRsdamlVO);

			Date now = new Date();
			List<ManageRsdawjEntity> rsdawjEntities = Lists.newArrayList();
			if (rsdamawjMap.containsKey(a.getRsdaml000())) {
				rsdawjEntities = rsdamawjMap.get(a.getRsdaml000()).stream()
					.map(e -> {
						// 修复报错问题
						if (e.getSort() == null) {
							e.setSort(Integer.MAX_VALUE);
						}
						if (e.getCreateTime() == null) {
							e.setCreateTime(now);
						}
						return e;
					})
					.sorted(Comparator
						.comparingInt(ManageRsdawjEntity::getSort)
						.thenComparingLong(p -> p.getCreateTime().getTime()))
					.collect(Collectors.toList());
			}
			String format = String.format("%s-%d-%s(%d/%d)", a.getRsdaml002(), a.getRsdaml003(), a.getRsdaml004(), a.getRsdaml005(),
				a.getRsdaml005());
			manageRsdamlVO.setLabel(format);
			manageRsdamlVO.setValue(manageRsdamlVO.getId());
			manageRsdamlVO.setImages(rsdawjEntities);
			result.add(manageRsdamlVO);
		});
		return result;
	}

	private List<ManageRsdawjEntity> doAdd(RsdamlPageUpdateDTO rsdamlPageUpdateDTO, List<ManageRsdawjEntity> rsdawjEntities) {
		// 大于等于rsdamlPageUpdateDTO.sort的都需要更新
		List<ManageRsdawjEntity> offsetList = rsdawjEntities.stream()
			.filter(item -> item.getSort() != null && item.getSort() >= rsdamlPageUpdateDTO.getSort())
			.map(item -> {
				ManageRsdawjEntity manageRsdawjEntity = new ManageRsdawjEntity();
				manageRsdawjEntity.setId(item.getId());
				manageRsdawjEntity.setIsDeleted(item.getIsDeleted());
				// 新增了几页，后续的sort需要增加
				manageRsdawjEntity.setSort(item.getSort() + rsdamlPageUpdateDTO.getPageCount());
				manageRsdawjEntity.setRsdawj001(String.format("%03d", manageRsdawjEntity.getSort()));
				return manageRsdawjEntity;
			}).filter(Objects::nonNull).collect(Collectors.toList());
		doUpdate(offsetList);
		return offsetList;
	}


	private List<ManageRsdawjEntity> doRemove(RsdamlPageUpdateDTO rsdamlPageUpdateDTO, List<ManageRsdawjEntity> rsdawjEntities) {

		List<ManageRsdawjEntity> updateList = Lists.newArrayList();

		// 在此范围 {minSort,maxSort} 的删除，超过的前移
		List<ManageRsdawjEntity> delList = rsdawjEntities.stream()
			.filter(item -> item.getSort() != null && item.getSort() >= rsdamlPageUpdateDTO.getSort() && item.getSort() <= rsdamlPageUpdateDTO.getSort())
			.collect(Collectors.toList());

		List<ManageRsdawjEntity> delData = delList.stream().map(item -> {
			ManageRsdawjEntity manageRsdawjEntity = new ManageRsdawjEntity();
			manageRsdawjEntity.setId(item.getId());
			manageRsdawjEntity.setIsDeleted(1);
			return manageRsdawjEntity;
		}).collect(Collectors.toList());
		updateList.addAll(delData);

		// 超过的maxSort，sort前移
		List<ManageRsdawjEntity> offsetList = rsdawjEntities.stream()
			.filter(item -> item.getSort() != null && item.getSort() > rsdamlPageUpdateDTO.getSort())
			.map(item -> {
				ManageRsdawjEntity manageRsdawjEntity = new ManageRsdawjEntity();
				manageRsdawjEntity.setId(item.getId());
				manageRsdawjEntity.setIsDeleted(0);
				manageRsdawjEntity.setSort(item.getSort() - 1);
				manageRsdawjEntity.setRsdawj001(String.format("%03d", manageRsdawjEntity.getSort()));
				return manageRsdawjEntity;
			}).filter(Objects::nonNull).collect(Collectors.toList());
		updateList.addAll(offsetList);
		doUpdate(updateList);
		return delList;
	}

	private List<ManageRsdawjEntity> doMove(RsdamlPageUpdateDTO rsdamlPageUpdateDTO, List<ManageRsdawjEntity> rsdawjEntities) {

		int minSort;
		int maxSort;
		int step;
		// 同一个目录，只改变sort到targetSort之间的数据
		if (StringUtils.equals(rsdamlPageUpdateDTO.getRsdaml000(), rsdamlPageUpdateDTO.getTargetRsdaml000())) {
			minSort = Math.min(rsdamlPageUpdateDTO.getSort(), rsdamlPageUpdateDTO.getTargetSort());
			maxSort = Math.max(rsdamlPageUpdateDTO.getSort(), rsdamlPageUpdateDTO.getTargetSort());
			step = rsdamlPageUpdateDTO.getSort() < rsdamlPageUpdateDTO.getTargetSort() ? -1 : 1;
		} else {
			// 不是同一个目录，直接更新目标目录页数
			RsdamlPageUpdateDTO addDto = new RsdamlPageUpdateDTO();
			addDto.setAdd(true);
			addDto.setSort(rsdamlPageUpdateDTO.getTargetSort());
			addDto.setRsdaml000(rsdamlPageUpdateDTO.getTargetRsdaml000());
			addDto.setA0000(rsdamlPageUpdateDTO.getA0000());
			addDto.setPageCount(1);
			changePageCount(addDto);

			//  只改变sort之后的数据
			minSort = rsdamlPageUpdateDTO.getSort();
			maxSort = Integer.MAX_VALUE;
			step = -1;
		}

		List<ManageRsdawjEntity> updateList = rsdawjEntities.stream()
			.filter(item -> item.getSort() != null && item.getSort() >= minSort && item.getSort() <= maxSort)
			.map(item -> {
				ManageRsdawjEntity manageRsdawjEntity = new ManageRsdawjEntity();
				manageRsdawjEntity.setId(item.getId());
				manageRsdawjEntity.setIsDeleted(0);
				if (item.getSort() == rsdamlPageUpdateDTO.getSort()) {
					manageRsdawjEntity.setRsdawj000(rsdamlPageUpdateDTO.getTargetRsdaml000());
					manageRsdawjEntity.setSort(rsdamlPageUpdateDTO.getTargetSort());
					manageRsdawjEntity.setRsdawj001(String.format("%03d", manageRsdawjEntity.getSort()));
				} else {
					manageRsdawjEntity.setSort(item.getSort() + step);
					manageRsdawjEntity.setRsdawj001(String.format("%03d", manageRsdawjEntity.getSort()));
				}
				return manageRsdawjEntity;
			}).collect(Collectors.toList());
		doUpdate(updateList);
		return updateList;
	}

	private int doUpdate(List<ManageRsdawjEntity> updateList) {
		AtomicInteger effectCount = new AtomicInteger(0);
		// 按照是否需要删除分组
		updateList.stream()
			.collect(Collectors.groupingBy(manageRsdawjEntity -> manageRsdawjEntity.getIsDeleted()))
			.entrySet().forEach(entry -> {
				// 批量逻辑删除
				if (entry.getKey() == 1) {
					List<Long> ids = entry.getValue().stream().map(ManageRsdawjEntity::getId).collect(Collectors.toList());
					rsdawjService.deleteLogic(ids);
					effectCount.addAndGet(ids.size());
				}    // 批量更新
				else {
					rsdawjService.updateBatchById(entry.getValue());
					effectCount.addAndGet(entry.getValue().size());
				}
			});
		return effectCount.get();
	}

	@Transactional
	@Override
	public int changePageCount(RsdamlPageUpdateDTO rsdamlPageUpdateDTO) {

		int pageChange = 0;
		// 先获得当前目录的所有文件
		// TODO：sort,create_time 为空时可能报错
		List<ManageRsdawjEntity> rsdawjEntities = rsdawjMapper.selectList(Wrappers.<ManageRsdawjEntity>lambdaQuery()
			.eq(ManageRsdawjEntity::getRsdawj000, rsdamlPageUpdateDTO.getRsdaml000())
			.eq(ManageRsdawjEntity::getA0000, rsdamlPageUpdateDTO.getA0000())
			.orderByAsc(ManageRsdawjEntity::getSort)
			.orderByAsc(ManageRsdawjEntity::getCreateTime)
		);

		// 新增页码
		if (rsdamlPageUpdateDTO.isAdd()) {
			doAdd(rsdamlPageUpdateDTO, rsdawjEntities);
			pageChange = rsdamlPageUpdateDTO.getPageCount();
		}
		// 删除或移动页码
		else {
			if (rsdamlPageUpdateDTO.isMove()) {
				doMove(rsdamlPageUpdateDTO, rsdawjEntities);
				// 不是同一个目录，改变页码
				if (StringUtils.equals(rsdamlPageUpdateDTO.getTargetRsdaml000(),
					rsdamlPageUpdateDTO.getRsdaml000()) == false) {
					pageChange = -1;
				}
			} else {
				doRemove(rsdamlPageUpdateDTO, rsdawjEntities);
				pageChange = -1;
			}
		}

		// 放到最后在获取目录，可以避免移动时候改变目录页数
		ManageRsdamlEntity manageRsdamlEntity = getOne(Wrappers.<ManageRsdamlEntity>lambdaQuery()
			.eq(ManageRsdamlEntity::getRsdaml000, rsdamlPageUpdateDTO.getRsdaml000()));
		manageRsdamlEntity.setRsdaml005(manageRsdamlEntity.getRsdaml005() + pageChange);
		// 如果是0，直接删除目录
		if (manageRsdamlEntity.getRsdaml005().equals(0)) {
			this.removeManageRsdamlEntity(Lists.newArrayList(manageRsdamlEntity.getId()));
			this.saveSorts(manageRsdamlEntity.getA0000());
		} else {
			// 更新目录页码
			this.updateById(manageRsdamlEntity);
		}
		return 1;
	}

	@Transactional
	@Override
	public int changePageNo(RsdamlPageChangeDTO pageChangeDTO) {

		List<ManageRsdamlDTO> rsdamlDTOS = getManageRsdawjEntities(pageChangeDTO);

		int maxPageNo = Math.max(pageChangeDTO.getNewPageNo(), pageChangeDTO.getOldPageNo());
		int minPageNO = Math.min(pageChangeDTO.getNewPageNo(), pageChangeDTO.getOldPageNo());

		// 新编号大，数字减1；新编号小，数字加1
		int flag = pageChangeDTO.getOldPageNo().compareTo(pageChangeDTO.getNewPageNo()) < 0 ? -1 : 1;

		List<ManageRsdawjEntity> dataForUpdate = Lists.newArrayList();
		rsdamlDTOS.stream().forEach(rsdamlDTO -> {
			rsdamlDTO.getRsdawjDTOList().forEach(rsdawjDTO -> {
				// 只处理范围内的东西
				if (rsdawjDTO.getPageNo() >= minPageNO && rsdawjDTO.getPageNo() <= maxPageNo) {

					int newPageNo;
					if (rsdawjDTO.getPageNo() == pageChangeDTO.getOldPageNo()) {
						newPageNo = pageChangeDTO.getNewPageNo();
					} else {
						newPageNo = rsdawjDTO.getPageNo() + flag;
					}
					Pair<ManageRsdamlDTO, Integer> mlByPageNo = getMlByPageNo(rsdamlDTOS, newPageNo);
					ManageRsdawjEntity update = new ManageRsdawjEntity();
					update.setId(rsdawjDTO.getId());
					update.setRsdawj000(mlByPageNo.getKey().getRsdaml000());
					update.setSort(mlByPageNo.getValue());
					update.setRsdawj001(String.format("%03d", mlByPageNo.getValue()));
					dataForUpdate.add(update);
				}
			});
		});
		if (dataForUpdate.isEmpty() == false) {
			List<ManageRsdawjEntity> oldDatas =
				rsdawjService.listByIds(dataForUpdate.stream().map(ManageRsdawjEntity::getId).collect(Collectors.toList()));
			rsdawjService.updateBatchById(dataForUpdate);
			dataForUpdate.stream().forEach(dateForUpdate -> {
				oldDatas.stream()
					.filter(oldData -> oldData.getId().equals(dateForUpdate.getId()))
					.findAny().ifPresent(oldData -> {
						ManageRsdawjEntity newData = ObjectUtil.clone(oldData);
						newData.setRsdawj000(dateForUpdate.getRsdawj000());
						newData.setSort(dateForUpdate.getSort());
						newData.setRsdawj001(dateForUpdate.getRsdawj001());
						logManager.doBizUpdate(pageChangeDTO.getA0000(), LogManager.TYPE_WJ, "调整页码", oldData, newData);
					});
			});
		}
		return 1;
	}

	private Pair<ManageRsdamlDTO, Integer> getMlByPageNo(List<ManageRsdamlDTO> rsdamlDTOS, int pageNo) {

		for (int i = 0; i < rsdamlDTOS.size(); i++) {
			ManageRsdamlDTO rsdamlDTO = rsdamlDTOS.get(i);
			if (rsdamlDTO.getStartPageNo() <= pageNo && rsdamlDTO.getEndPageNo() >= pageNo) {
				return Pair.of(rsdamlDTO, pageNo - rsdamlDTO.getStartPageNo() + 1);
			}
		}
		return Pair.of(null, null);
	}


	private List<ManageRsdamlDTO> getManageRsdawjEntities(RsdamlPageChangeDTO pageChangeDTO) {

		// TODO：在散材料模式下，会多查数据，待优化
		Map<String, List<ManageRsdawjEntity>> rsdamawjMap = rsdawjMapper.selectList(
				Wrappers.<ManageRsdawjEntity>lambdaQuery()
					.eq(ManageRsdawjEntity::getA0000, pageChangeDTO.getA0000())
					.isNotNull(ManageRsdawjEntity::getRsdawj000)
			).stream()
			.collect(Collectors.groupingBy(ManageRsdawjEntity::getRsdawj000));

		LambdaQueryWrapper<ManageRsdamlEntity> queryWrapper = Wrappers.<ManageRsdamlEntity>lambdaQuery()
			.eq(ManageRsdamlEntity::getA0000, pageChangeDTO.getA0000()).orderByAsc(ManageRsdamlEntity::getClassSort)
			.orderByAsc(ManageRsdamlEntity::getRsdaml003);

		// 查询散材料
		if (pageChangeDTO.getStatus().equals(0)) {
			queryWrapper.eq(ManageRsdamlEntity::getStatus, pageChangeDTO.getStatus());
		}

		List<ManageRsdamlDTO> rsdamlEntities = this.list(queryWrapper)
			.stream().map(item -> {
				ManageRsdamlDTO manageRsdawjDTO = new ManageRsdamlDTO();
				Func.copy(item, manageRsdawjDTO);
				return manageRsdawjDTO;
			}).collect(Collectors.toList());

		AtomicInteger pageCount = new AtomicInteger(0);

		rsdamlEntities.stream().forEach(rsdamlDTO -> {
			Date now = new Date();
			if (rsdamawjMap.containsKey(rsdamlDTO.getRsdaml000())) {
				List<ManageRsdawjDTO> rsdawjDTOS = rsdamawjMap.get(rsdamlDTO.getRsdaml000()).stream()
					.map(rsdawjEntity -> {
						// 修复报错问题
						if (rsdawjEntity.getSort() == null) {
							rsdawjEntity.setSort(Integer.MAX_VALUE);
						}
						if (rsdawjEntity.getCreateTime() == null) {
							rsdawjEntity.setCreateTime(now);
						}
						ManageRsdawjDTO manageRsdawjDTO = new ManageRsdawjDTO();
						Func.copy(rsdawjEntity, manageRsdawjDTO);
						// 记录文档全局页数
						manageRsdawjDTO.setPageNo(rsdawjEntity.getSort() + pageCount.get());
						return manageRsdawjDTO;
					})
					// 排序必须小于或等于目录页数
					.filter(e -> e.getSort() <= rsdamlDTO.getRsdaml005())
					.sorted(Comparator
						.comparingInt(ManageRsdawjEntity::getSort)
						.thenComparingLong(p -> p.getUpdateTime().getTime()))
					.collect(Collectors.toList());
				rsdamlDTO.setRsdawjDTOList(rsdawjDTOS);
			}
			rsdamlDTO.setStartPageNo(pageCount.get() + 1);
			// 增加目录页数
			int endPageNo = pageCount.addAndGet(rsdamlDTO.getRsdaml005());
			rsdamlDTO.setEndPageNo(endPageNo);
		});
		return rsdamlEntities;
	}

	@Transactional
	@Override
	public boolean deleteByIds(String idStrList) {
		List<Long> ids = Func.toLongList(idStrList);
		ManageRsdamlEntity byId = this.getById(ids.get(0));
		boolean res = deleteLogic(ids);
		if (res) {
			// 自动排序
			String a0000 = byId.getA0000();
			ManageRsdamlEntity query = new ManageRsdamlEntity();
			query.setA0000(a0000);
			QueryWrapper<ManageRsdamlEntity> manageRsdamlEntityQueryWrapper = Condition.getQueryWrapper(query).orderByAsc("class_sort").orderByAsc(
				"rsdaml003");
			AtomicInteger pageNo = new AtomicInteger();
			List<ManageRsdamlEntity> collect = this.list(manageRsdamlEntityQueryWrapper).stream().map(item -> {
				item.setRsdaml003(pageNo.incrementAndGet());
				return item;
			}).collect(Collectors.toList());
			this.saveBatch(collect);
		}
		return res;
	}

	@Override
	public void saveSorts(String a0000) {
		LambdaQueryWrapper<ManageRsdamlEntity> queryWrapper = Wrappers.<ManageRsdamlEntity>lambdaQuery().eq(ManageRsdamlEntity::getA0000, a0000)
			.orderByAsc(ManageRsdamlEntity::getClassSort)
			.orderByAsc(ManageRsdamlEntity::getRsdaml003);
		List<ManageRsdamlEntity> list = this.list(queryWrapper);
		Map<Integer, List<ManageRsdamlEntity>> mlGroup = list.stream().collect(Collectors.groupingBy(ManageRsdamlEntity::getClassSort));

		List<ManageRsdamlEntity> allUpdates = mlGroup
			.keySet().stream().sorted()
			.map(key -> {
				AtomicInteger count = new AtomicInteger(0);
				List<ManageRsdamlEntity> updates = mlGroup.get(key).stream()
					.sorted(Comparator.comparingInt(ManageRsdamlEntity::getRsdaml003))
					.map(item -> {
						ManageRsdamlEntity update = new ManageRsdamlEntity();
						update.setId(item.getId());
						update.setRsdaml003(count.incrementAndGet());
						return update;
					})
					.collect(Collectors.toList());
				return updates;
			})
			.flatMap(Collection::stream)
			.collect(Collectors.toList());

		this.updateBatchById(allUpdates);
//		updateRsdamlBatch(list);x
	}


	@Transactional
	@Override
	public boolean saveManageRsdamlEntity(ManageRsdamlEntity rsdaml) {

		boolean result = this.save(rsdaml);
		this.saveSorts(rsdaml.getA0000());
		logManager.doAdd(rsdaml.getA0000(), LogManager.TYPE_ML, rsdaml);
		return result;
	}

	@Transactional
	@Override
	public boolean updateManageRsdamlEntity(ManageRsdamlEntity rsdaml) {

		ManageRsdamlEntity oldData = getById(rsdaml.getId());

		boolean result = this.updateById(rsdaml);
		this.saveSorts(rsdaml.getA0000());

		logManager.doUpdate(rsdaml.getA0000(), LogManager.TYPE_ML, oldData, rsdaml);
		return result;
	}

	@Override
	public boolean saveOrUpdateManageRsdamlEntity(ManageRsdamlEntity rsdaml) {

		ManageRsdamlEntity oldData = this.getById(rsdaml.getId());

		boolean result = this.saveOrUpdate(rsdaml);


		// 查询当前类目下比当前编号的大的数据
		LambdaQueryWrapper<ManageRsdamlEntity> query = Wrappers.<ManageRsdamlEntity>lambdaQuery()
			.eq(ManageRsdamlEntity::getA0000, rsdaml.getA0000())
			.eq(ManageRsdamlEntity::getClassSort, rsdaml.getClassSort())
			.ge(ManageRsdamlEntity::getRsdaml003, rsdaml.getRsdaml003())
			.not(q -> q.eq(ManageRsdamlEntity::getId, rsdaml.getId()));
		// 该序列号之后的目录编号自动加1
		List<ManageRsdamlEntity> list = this.list(query);
		list.stream().forEach(item -> {
			item.setRsdaml003(item.getRsdaml003() + 1);
		});
		this.updateBatchById(list);

		if (result) {
			if (oldData == null) {
				logManager.doAdd(rsdaml.getA0000(), LogManager.TYPE_ML, rsdaml);
			} else {
				logManager.doUpdate(rsdaml.getA0000(), LogManager.TYPE_ML, oldData, rsdaml);
			}

			this.saveSorts(rsdaml.getA0000());
		}
		return result;
	}

	@Override
	public boolean removeManageRsdamlEntity(List<Long> ids) {
		List<ManageRsdamlEntity> manageRsdamlEntities = this.listByIds(ids);
		boolean result = this.deleteLogic(ids);
		if (manageRsdamlEntities.isEmpty() == false) {
			manageRsdamlEntities.parallelStream().forEach(item -> logManager.doDel(item.getA0000(), LogManager.TYPE_ML, item));
		}
		return result;
	}

	@Override
	public boolean updateSanCaiLiaoStatus(String a0000) {
		ManageRsdamlEntity dataForUpdate = new ManageRsdamlEntity();
		dataForUpdate.setStatus(ConstantDigit.A01_STATUS_USER);
		LambdaQueryWrapper<ManageRsdamlEntity> query = Wrappers.<ManageRsdamlEntity>lambdaQuery()
			.eq(ManageRsdamlEntity::getA0000, a0000)
			.eq(ManageRsdamlEntity::getStatus, 0);
		boolean update = this.update(dataForUpdate, query);
		return update;
	}

	@Override
	public List<ManageRsdamlEntity> getByRsdaml000(List<String> rsdaml000List) {
		return this.list(Wrappers.<ManageRsdamlEntity>lambdaQuery()
			.in(ManageRsdamlEntity::getRsdaml000, rsdaml000List));
	}

	private List<CatalogItem> createCatalogDirs() {
		List<CatalogItem> dirs = new ArrayList<CatalogItem>();
		//查询字典
		List<Dict> dicts =
			dictService.list(Wrappers.<Dict>lambdaQuery().ne(Dict::getDictKey, "-1").eq(Dict::getCode, CATALOG_DIR_DICT).orderByAsc(Dict::getSort));
		CatalogItem preParentItem = null;
		for (Dict dict : dicts) {
			CatalogItem catalogItem = new CatalogItem();
			catalogItem.setId(dict.getId().toString());
			catalogItem.setParentId(dict.getParentId().toString());
			catalogItem.setClassNo(dict.getDictKey());
			catalogItem.setRsdaml002(dict.getDictValue());
			catalogItem.setRsdaml004(dict.getDictValue());
			catalogItem.setRsdaml005(0);
			catalogItem.setChildren(new ArrayList<CatalogItem>());
			if (preParentItem != null && preParentItem.getId().equals(catalogItem.getParentId())) {
				preParentItem.getChildren().add(catalogItem);
				catalogItem.setParent(preParentItem);
			} else {
				dirs.add(catalogItem);
				preParentItem = catalogItem;
			}

		}
		return dirs;
	}

	private CatalogItem getParentCatalogItem(List<CatalogItem> dirs, CatalogItem classNo) {
		for (CatalogItem catalogItem : dirs) {
			if (catalogItem.getClassNo().equals(classNo.getClassNo())) {
				return catalogItem;
			}
			if (Func.isNotEmpty(catalogItem.getChildren())) {
				CatalogItem item = getParentCatalogItem(catalogItem.getChildren(), classNo);
				if (item != null) {
					return item;
				}
			}
		}
		return null;
	}

	private void updateCatalogCount(CatalogItem item, int count) {
		item.setRsdaml005(item.getRsdaml005() + count);
		if (item.getParent() != null) {
			updateCatalogCount(item.getParent(), count);
		}
	}

	private void removeEmptyCatalog(List<CatalogItem> catalogItems) {
		List<CatalogItem> rmCatalogs = new ArrayList<CatalogItem>();
		//遍历去掉数量为0的目录
		for (CatalogItem catalogItem : catalogItems) {
			if (catalogItem.getRsdaml000() != null) {
				continue;
			}
			if (!hasRsdaml(catalogItem)) {
				rmCatalogs.add(catalogItem);
			}
			if (!catalogItem.getChildren().isEmpty()) {
				removeEmptyCatalog(catalogItem.getChildren());
			}
		}
		catalogItems.removeAll(rmCatalogs);
	}

	private boolean hasRsdaml(CatalogItem catalogItem) {
		for (CatalogItem subItem : catalogItem.getChildren()) {
			if (subItem.getChildren() != null && subItem.getChildren().size() > 0) {
				if (hasRsdaml(subItem)) {
					return true;
				}
			}
			if (subItem.getRsdaml005() > 0) {
				return true;
			}
		}
		return false;
	}

}
